﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Data;
using System.Threading;


namespace EmaillSend
{
    public class SendMailThread
    {
        private Hashtable table = new Hashtable();
        private CommonDBUtils dbutils = new CommonDBUtils();
        
        public string initServer()
        {            
            //删除已经发送的邮件
            dbutils.ExeSQL("delete from MailSendLog where IsSend='1'");

            DataSet setServer = dbutils.ReturnDataSet("select * from MailServer where IsActive=1");
            IList<MailServer> listServer = new List<MailServer>();
            foreach (DataRow row in setServer.Tables[0].Rows)
            {
                MailServer server = new MailServer();
                server.id = row[0].ToString();
                server.servername = row[1].ToString();
                server.port = (int)row[2];
                server.mailaddress = row[3].ToString();
                server.account = row[4].ToString();
                server.password = row[5].ToString();
                server.showname = row[6].ToString();
                server.backaddress = row[7].ToString();
                server.type = (int)row[11];
                listServer.Add(server);
            }
            int count = setServer.Tables[0].Rows.Count*Convert.ToInt32(Properties.Settings.Default.SendMaxMail);
            DataSet mail = dbutils.ReturnDataSet("select top " + count + " * from MailSendLog");
            if (mail.Tables[0].Rows.Count <= 0)
            {
                return "没有需要发送的邮箱地址！";
            }
            MailThread.guidlist.Clear();
            MailServer curServer = null;
            int i = -1;
            //ManualResetEvent eventX = new ManualResetEvent(false);
            ThreadPool.SetMaxThreads(20, 20);
            foreach (DataRow row in mail.Tables[0].Rows)
            {
                i++;
                if (i >= listServer.Count)
                {
                    i = 0;
                    //listServer.Remove(curServer);
                }
                curServer = listServer[i];
                string address=row[1].ToString();
                string contentId = row[2].ToString();
                if (!table.ContainsKey(contentId))
                {
                    this.loadContent(contentId);
                }
                curServer.addSendParam(new SendParam((MailContent)table[contentId], address, row[0].ToString()));
                //MailParam param = new MailParam(curServer, (MailContent)table[contentId], address,row[0].ToString());
                //MailThread thread = new MailThread();
               // thread.eventX = eventX;
                //ThreadPool.QueueUserWorkItem(new WaitCallback(thread.sendMail),param);
            }

            //将各个邮箱服务器加入到线程中进行发送
            foreach (MailServer server in listServer)
            {
                MailThread thread = new MailThread();
                ThreadPool.QueueUserWorkItem(new WaitCallback(thread.sendMail), server);
            }

            int maxWorkerThreads, workerThreads;
            int portThreads;
            while (true)
            {
                /*
                 GetAvailableThreads()：检索由 GetMaxThreads 返回的线程池线程的最大数目和当前活动数目之间的差值。
                 而GetMaxThreads 检索可以同时处于活动状态的线程池请求的数目。
                 通过最大数目减可用数目就可以得到当前活动线程的数目，如果为零，那就说明没有活动线程，说明所有线程运行完毕。
                 */
                ThreadPool.GetMaxThreads(out maxWorkerThreads, out portThreads);
                ThreadPool.GetAvailableThreads(out workerThreads, out portThreads);
                if (maxWorkerThreads - workerThreads == 0)
                {                    
                    break;
                }
                //Console.WriteLine("线程还没有结束，继续等待。。。。");
                Thread.Sleep(30000);
            }
            
            //进行数据库的更新删除已经执行的
            LogHelper.InfoLog("邮件发送完成，共发送" + mail.Tables[0].Rows.Count + "封，成功了" + MailThread.guidlist.Count + "封");
            //循环释放邮件客户端
            foreach (MailServer server in listServer)
            {
                server.Disponse();
            }
            List<string> sql = new List<string>();
            for (int j = 0; j < MailThread.guidlist.Count; j++)
            {
                sql.Add("delete from MailSendLog where id = "+MailThread.guidlist[j]);                
            }
            dbutils.ExeBatchSQL(sql);

            return "邮件发送完成，共发送"+mail.Tables[0].Rows.Count+"封，成功了"+MailThread.guidlist.Count+"封";
        }

        public void loadContent(string id)
        {
            DataSet set = dbutils.ReturnDataSet("select * from MailContent where id = "+id);
            if (set == null || set.Tables[0].Rows.Count == 0)
            {
                throw new Exception("ID号为"+id+"的内容不存在！");
            }
            
            string subject = set.Tables[0].Rows[0][1] == null ? "" : set.Tables[0].Rows[0][1].ToString();
            string content = set.Tables[0].Rows[0][3] == DBNull.Value ? "" : System.Text.Encoding.UTF8.GetString((byte[])set.Tables[0].Rows[0][3]);
            string imgpath = set.Tables[0].Rows[0][4] == null ? "" : set.Tables[0].Rows[0][4].ToString();
            MailContent mailContent = new MailContent(id, subject, content, imgpath);
            table.Add(id, mailContent);            
        }      

    }
}
